package pogvue.datamodel;

import pogvue.util.Format;

import java.awt.*;

import java.util.*;

public class SequenceFeature {
    public int      start;
    public int      end;
    public String   type;
    public String   description;
    public Color    color;
    public Sequence sequence;
    public String   id;
    public double   score;
    public double   score2;
    public int      hitlen;
    public int      strand;
    public double   pvalue;
    public double   pid;
    public String   type2;
    public SequenceFeature hit = null;
    public String   phase = ".";

    public String alignString;
    public Hashtable scoreVector = null;

    public Sequence seq;

    public  Hashtable scores = null;

    Vector  feat;

    public SequenceFeature() {
    }
    
    public SequenceFeature(Sequence sequence,String type, int start, int end, String description) {
	this.sequence = sequence;
	this.type = type;
	this.start = start;
	this.end = end;
	this.description = description;
	
	setColor();
    }


  public String toGFFString() {
	String gff = id + "\t" + type + "\tfeature\t" + start + "\t" + end + "\t" + score + "\t" + strand + "\t" + phase;
	
	if (hit != null) {
	    gff = gff + "\t" + hit.getId() + "\t" + hit.getStart() + "\t" + hit.getEnd();
	}
	return gff;
    }
    
    public void setScores(Hashtable hash) {
	this.scores = hash;
    }
    public Hashtable getScores() {
	return scores;
    }
    public double getScoreAt(int i) {
	if (scores != null && scores.containsKey(i)) {
	    return ((Double)scores.get((int)i)).doubleValue();
	} else {
	    return 0.0;

	}
    }
    public void setScoreVector(Hashtable hash) {
	this.scoreVector = hash;
    }
    public Hashtable getScoreVector() {
	return scoreVector;
    }
    public Vector getScoreVectorAt(int i) {
	if (scoreVector != null && scoreVector.containsKey(i)) {
	    return (Vector)scoreVector.get((int)i);
	} else {
	    return new Vector();
	}
    }
    
    public int getLength() {
	return (end - start + 1);
    }
    public void setAlignString(String str) {
	this.alignString = str;
    }
    public String getAlignString() {
	return alignString;
    }
    public void setType(String type) {
	this.type = type;
    }
    public void setType2(String type2) {
	this.type2 = type2;
    }
    public String getType2() {
	return type2;
    }
    public void setHitFeature(SequenceFeature hit) {
	this.hit = hit;
    }
    public SequenceFeature getHitFeature() {
	return hit;
    }
    public double getScore() {
	return score;
    }
    public void setScore(double score) {
	this.score = score;
    }
    public String getId() {
	return this.id;
    }
    public void setId(String id) {
	this.id = id;
    }
    public void setSequence(Sequence seq) {
	this.sequence = seq;
    }
    public Sequence getSequence() {
	return sequence;
    }
    public void setPhase(String phase) {
	this.phase = phase;
    }
    public String getPhase() {
	return phase;
    }
    public void setStart(int start) {
	this.start = start;
    }
    public void setEnd(int end) {
	this.end = end;
    }
    public int getStrand() {
	return strand;
    }
    public void setStrand(int strand) {
	this.strand = strand;
    }
    public int getStart() {
	return start;
    }
    
    public int getEnd() {
	return end;
    }
    
    public String getType() {
	return type;
    }
    
    public String getDescription() {
	return description;
    }
    
    double getPValue() {
	return pvalue;
    }
    void setPValue(double value) {
	this.pvalue = value;
    }
    double getPercentId() {
	return pid;
    }
    void setPercentId(double pid) {
	this.pid = pid;
    }
    public Color getColor() {
	return color;
    }
    
    public void setScore2(double s) {
	this.score2 = s;
    }
    public double getScore2() {
	return score2;
    }
    public void setHitlen(int len) {
	this.hitlen = len;
    }
    public int getHitlen() {
	return hitlen;
    }
    private void setColor() {
	if (type.equals("CHAIN")) {
	    color = Color.white;
	} else if (type.equals("DOMAIN")) {
	    color = Color.white;
	} else if (type.equals("TRANSMEM")) {
	    color = Color.red.darker();
	} else if (type.equals("SIGNAL")) {
	    color = Color.cyan;
	} else if (type.equals("HELIX")) {
	    color = Color.magenta;
	} else if (type.equals("TURN")) {
	    color = Color.cyan;
	} else if (type.equals("SHEET")) {
	    color = Color.yellow;
	} else if (type.equals("STRAND")) {
	    color = Color.yellow;
	} else if (type.equals("CARBOHYD")) {
	    color = Color.pink;
	} else if (type.equals("ACT_SITE")) {
	    color = Color.red;
	} else if (type.equals("TRANSIT")) {
	    color = Color.orange;
	} else if (type.equals("VARIANT")) {
	    color = Color.orange.darker();
	} else if (type.equals("BINDING")) {
	    color = Color.blue;
	} else if (type.equals("DISULFID")) {
	    color = Color.yellow.darker();
	} else if (type.equals("NP_BIND")) {
	    color = Color.red;
	} else if (type.indexOf("BIND") > 0) {
	    color = Color.red;
	} else {
	    color = Color.lightGray;
	}
    }
    public String print() {
	String tmp = new Format("%15s").form(type);
	tmp = tmp +  new Format("%6d").form(start);
	tmp = tmp +  new Format("%6d").form(end);
	tmp = tmp +  " " + description;
	return tmp;
    }
    public void draw(Graphics g, int fstart, int fend, int x1, int y1, int width, int height) {
	g.setColor(new Color((float)(Math.random()),(float)(Math.random()),(float)(Math.random())));

	int xstart = start;
	int xend = end;
	long tstart = System.currentTimeMillis();

	if (!(xend < fstart && xstart > fend)) {
	    
	    if (xstart > fstart) {
		x1 = x1 + (xstart-fstart)*width;
		fstart = xstart;
	    }
	    
	    if (xend < fend) {
		fend = xend;
	    }
	    
	    for (int i = fstart; i <= fend; i++) {
		String s = sequence.sequence.substring(i,i+1);
		if (!(s.equals(".") || s.equals("-") || s.equals(" "))) {
		    g.fillRect(x1+(i-fstart)*width,y1,width,height);
		} else {
		    g.drawString("-",x1+(i-fstart)*width,y1+height);
		}
	    }
	    
	}
	long tend = System.currentTimeMillis();
	System.out.println("Time = " + (tend-tstart) + "ms");
	
    }

  public void addFeatures(Vector feat) {
    for (int i = 0; i < feat.size(); i++) {
      SequenceFeature sf = (SequenceFeature)feat.elementAt(i);

      addFeature(sf);
    }
  }
    public void addFeature(SequenceFeature sf) {
	if (feat == null) {
	    feat = new Vector();

	    feat.addElement(sf);
	    
	    start  = sf.getStart();
	    end    = sf.getEnd();
	    
	    strand = sf.getStrand();
	    type   = sf.getType();
	} else {
	    feat.addElement(sf);

	    if (sf.getStart() < start) {
		start = sf.getStart();
	    }
	    if (sf.getEnd() > end) {
		end   = sf.getEnd();
	    }
	}
    }

    public Vector getFeatures() {
	return feat;
    }

    public static void main(String[] args) {
	SequenceFeature sf = new SequenceFeature();
	
	System.out.println("Feature " + sf);
    }
    public static final int CHAIN    = 0;
    public static final int DOMAIN   = 1;
    public static final int TRANSMEM = 2;
    public static final int SIGNAL   = 3;
    public static final int HELIX    = 4;
    public static final int TURN     = 5;
    public static final int SHEET    = 6;
    public static final int CARBOHYD = 7;
    public static final int ACT_SITE = 8;
    public static final int TRANSIT  = 9;
    public static final int VARIANT  = 10;
    public static final int BINDING  = 11;

}

